package com.xj.util;

import java.io.StringReader;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.ArrayUtils;

import antlr.RecognitionException;
import antlr.TokenStreamException;

import com.sdicons.json.mapper.JSONMapper;
import com.sdicons.json.mapper.MapperException;
import com.sdicons.json.model.JSONArray;
import com.sdicons.json.model.JSONValue;
import com.sdicons.json.parser.JSONParser;

public class JsonUtil {

	/**
	 * 可以将pojo对象、HashMap、ArrayList转换成json字符串
	 * 
	 * @param obj
	 *            传入的pojo对象、HashMap或ArrayList
	 * @return 返回json字符串
	 */
	public static String javaToJsonStr(Object obj) {
		return ((obj instanceof List) || (obj instanceof Set) ? net.sf.json.JSONArray
				.fromObject(obj).toString() : net.sf.json.JSONObject
				.fromObject(obj).toString());
	}

	/**
	 * 可以将pojo对象、HashMap、ArrayList转换成json字符串，过滤掉不进行转换的属性
	 * 
	 * @param obj
	 *            传入的pojo对象、HashMap或ArrayList
	 * @param strs
	 *            传入不需要转换的属性，格式为:"attr1,attr2,attr3"
	 * @return 返回json字符串
	 */
	public static String javaToJsonStr(Object obj, String strs) {
		net.sf.json.JsonConfig jc = new net.sf.json.JsonConfig();
		jc.setExcludes(strs.split(","));
		return ((obj instanceof List) || (obj instanceof Set) ? net.sf.json.JSONArray
				.fromObject(obj, jc).toString() : net.sf.json.JSONObject
				.fromObject(obj, jc).toString());
	}

	/**
	 * 将json字符串转换成pojo对象、HashMap
	 * 
	 * @param str
	 *            传入的json字符串
	 * @param clas
	 *            传入的pojo或HashMap类型
	 * @return 返回pojo对象或HashMap
	 */
	public static Object jsonStrToJava(String str, Class<?> clazz) {
		return net.sf.json.JSONObject.toBean(
				net.sf.json.JSONObject.fromObject(str), clazz);
	}

	public static Object jsonStrToJava(String str, Class<?> clazz, Map<?, ?> col) {
		return net.sf.json.JSONObject.toBean(
				net.sf.json.JSONObject.fromObject(str), clazz, col);
	}

	/**
	 * JAVA对象转换成JSON字符串
	 * 
	 * @param obj
	 * @return
	 * @throws MapperException
	 */
	public static String objectToJsonStr(Object obj) {
		try {
			JSONValue jsonValue = JSONMapper.toJSON(obj);
			return jsonValue.render(false);
		} catch (MapperException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 重载objectToJsonStr方法
	 * 
	 * @param obj
	 *            需要转换的JAVA对象
	 * @param format
	 *            是否格式化
	 * @return
	 * @throws MapperException
	 */
	public static String objectToJsonStr(Object obj, boolean format)
			throws MapperException {
		JSONValue jsonValue = JSONMapper.toJSON(obj);
		String jsonStr = jsonValue.render(format);
		return jsonStr;
	}

	/**
	 * JSON字符串转换成JAVA对象
	 * 
	 * @param jsonStr
	 * @param cla
	 * @return
	 * @throws MapperException
	 * @throws TokenStreamException
	 * @throws RecognitionException
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public static Object jsonStrToObject(String jsonStr, Class<?> cla)
			throws MapperException, TokenStreamException, RecognitionException {
		Object obj = null;
		try {
			JSONParser parser = new JSONParser(new StringReader(jsonStr));
			JSONValue jsonValue = parser.nextValue();
			if (jsonValue instanceof com.sdicons.json.model.JSONArray) {
				List list = new ArrayList();
				JSONArray jsonArray = (JSONArray) jsonValue;
				for (int i = 0; i < jsonArray.size(); i++) {
					JSONValue jsonObj = jsonArray.get(i);
					Object javaObj = JSONMapper.toJava(jsonObj, cla);
					list.add(javaObj);
				}
				obj = list;
			} else if (jsonValue instanceof com.sdicons.json.model.JSONObject) {
				obj = JSONMapper.toJava(jsonValue, cla);
			} else {
				obj = jsonValue;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return obj;
	}

	/**
	 * 将JSON字符串转换成JAVA集合
	 * 
	 * @param jsonStr
	 * @return
	 * @throws TokenStreamException
	 * @throws RecognitionException
	 * @throws MapperException
	 */
	public static LinkedList<?> jsonStrToArray(String jsonStr)
			throws TokenStreamException, RecognitionException, MapperException {
		JSONParser parser = new JSONParser(new StringReader(jsonStr));
		JSONValue jsonValue = parser.nextValue();
		LinkedList<?> list = (LinkedList<?>) JSONMapper.toJava(jsonValue);
		return list;
	}

	/**
	 * 将JAVA对象转换成JSON字符串， 只转换第一层数据
	 * 
	 * @param obj
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	@SuppressWarnings("rawtypes")
	public static String simpleObjectToJsonStr(Object obj)
			throws IllegalArgumentException, IllegalAccessException {
		if (obj == null) {
			return "null";
		}
		Class valueType = obj.getClass();
		Class[] classes = { int.class, Integer.class, boolean.class,
				Boolean.class, double.class, Double.class, float.class,
				Float.class, long.class, Long.class, byte.class, Byte.class,
				short.class, Short.class, char.class, Character.class,
				String.class };
		if (ArrayUtils.contains(classes, valueType)) {
			return obj.toString();
		}
		if (obj.getClass() == ArrayList.class) {
			return simpleListToJsonStr((List<?>) obj);
		}
		if (obj.getClass() == HashMap.class) {
			return simpleMapToJsonStr((Map<?, ?>) obj);
		}
		String jsonStr = "{";
		Field fields[] = valueType.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			if (field.getType() == long.class) {
				jsonStr += "\"" + field.getName() + "\":" + field.getLong(obj)
						+ ",";
			} else if (field.getType() == double.class) {
				jsonStr += "\"" + field.getName() + "\":"
						+ field.getDouble(obj) + ",";
			} else if (field.getType() == float.class) {
				jsonStr += "\"" + field.getName() + "\":" + field.getFloat(obj)
						+ ",";
			} else if (field.getType() == int.class) {
				jsonStr += "\"" + field.getName() + "\":" + field.getInt(obj)
						+ ",";
			} else if (field.getType() == boolean.class) {
				jsonStr += "\"" + field.getName() + "\":"
						+ field.getBoolean(obj) + ",";
			} else if (field.getType() == byte.class) {
				jsonStr += "\"" + field.getName() + "\":" + field.getByte(obj)
						+ ",";
			} else if (field.getType() == short.class) {
				jsonStr += "\"" + field.getName() + "\":" + field.getShort(obj)
						+ ",";
			} else if (field.getType() == char.class) {
				jsonStr += "\"" + field.getName() + "\":" + field.getChar(obj)
						+ ",";
			} else if (field.getType() == Integer.class
					|| field.getType() == Boolean.class
					|| field.getType() == Double.class
					|| field.getType() == Float.class
					|| field.getType() == Long.class
					|| field.getType() == Byte.class
					|| field.getType() == Short.class
					|| field.getType() == Character.class) {
				jsonStr += "\"" + field.getName() + "\":" + field.get(obj)
						+ ",";
			} else {
				jsonStr += "\"" + field.getName() + "\":\"" + field.get(obj)
						+ "\",";
			}
		}
		jsonStr = jsonStr.substring(0, jsonStr.length() - 1);
		jsonStr += "}";
		return jsonStr;
	}

	/**
	 * 将JAVA的LIST转换成JSON字符串， 只转换第一层数据
	 * 
	 * @param list
	 * @return
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static String simpleListToJsonStr(List<?> list)
			throws IllegalArgumentException, IllegalAccessException {
		if (list == null || list.size() == 0) {
			return "[]";
		}
		StringBuffer sb = new StringBuffer();
		sb.append("[");
		for (int i = 0; i < list.size(); i++) {
			Object object = list.get(i);
			if (i == 0) {
				sb.append(simpleObjectToJsonStr(object));
			} else {
				sb.append(",");
				sb.append(simpleObjectToJsonStr(object));
			}
		}
		sb.append("]");
		return sb.toString();
	}

	/**
	 * 将JAVA的MAP转换成JSON字符串， 只转换第一层数据
	 * 
	 * @param map
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private static String simpleMapToJsonStr(Map<?, ?> map) {
		if (map == null || map.isEmpty()) {
			return "null";
		}
		StringBuffer sb = new StringBuffer();
		sb.append("{");
		Set<?> keySet = map.keySet();
		Iterator it = (Iterator) keySet.iterator();
		while (true) {
			if (!it.hasNext()) {
				break;
			}
			Object key = it.next();
			Class valueType = map.get(key).getClass();
			Class[] classes = { int.class, Integer.class, boolean.class,
					Boolean.class, double.class, Double.class, float.class,
					Float.class, long.class, Long.class, byte.class,
					Byte.class, short.class, Short.class, char.class,
					Character.class, };
			if (ArrayUtils.contains(classes, valueType)) {
				sb.append("\"");
				sb.append(key);
				sb.append("\":");
				sb.append(map.get(key));
				if (it.hasNext()) {
					sb.append(",");
				}
			} else {
				sb.append("\"");
				sb.append(key);
				sb.append("\":\"");
				sb.append(map.get(key));
				if (it.hasNext()) {
					sb.append("\",");
				}
			}
		}
		sb.append("}");
		return sb.toString();
	}
}
